package com.shopping_back.serviceImpl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shopping_back.common.enums.EmailTemplateEnum;
import com.shopping_back.mapper.UserAccountMapper;
import com.shopping_back.pojo.entity.UserAccount;
import com.shopping_back.service.CaptchaService;
import jakarta.annotation.Resource;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户账户表 服务实现类
 * </p>
 *
 * @author Jack
 * @since 2025-07-12
 */
@Service
public class CaptchaServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements CaptchaService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private JavaMailSender mailSender;

    // 验证码存储前缀（区分邮箱/手机）
    private static final String EMAIL_CAPTCHA_PREFIX = "captcha:email:";

    @Override
    public boolean sendEmailCaptcha(String email) {
        String redisKey = EMAIL_CAPTCHA_PREFIX + email;
        EmailTemplateEnum res = EmailTemplateEnum.REGISTRATION_CODE;
        System.out.println(res.getClass());
        System.out.println(res.getDeclaringClass());
        return sendCaptcha(redisKey, email, res);
    }

    private boolean sendCaptcha(String redisKey, String email, EmailTemplateEnum template) {
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(redisKey);

        // 1. 校验发送频率和次数
        String sendCount = hashOps.get("sendCount");
        String lastSendTime = hashOps.get("lastSendTime");

        // 次数超限（5次/分钟）
        if (StringUtils.isNotBlank(sendCount) && Integer.parseInt(sendCount) >= 5) {
            hashOps.expire(24, TimeUnit.HOURS); // 封禁24小时
            throw new RuntimeException("验证码发送过于频繁，请24小时后重试");
        }

        // 频率超限（1次/分钟）
        if (StringUtils.isNotBlank(lastSendTime)) {
            long elapsed = System.currentTimeMillis() - Long.parseLong(lastSendTime);
            if (elapsed < 60 * 1000) {
                throw new RuntimeException("验证码发送过于频繁，请1分钟后重试");
            }
        }

        // 2. 生成验证码
        String captcha = RandomStringUtils.randomNumeric(6);
        int newSendCount = StringUtils.isNotBlank(sendCount) ? Integer.parseInt(sendCount) + 1 : 1;

        // 3. 发送邮件
        try {
            sendEmail(email, template.getSubject(), template.format(captcha));
        } catch (MessagingException e) {
            throw new RuntimeException("邮件发送失败", e);
        }

        // 4. 存储到Redis（5分钟过期）
        hashOps.put("captcha", captcha);
        hashOps.put("sendCount", String.valueOf(newSendCount));
        hashOps.put("lastSendTime", String.valueOf(System.currentTimeMillis()));
        hashOps.expire(5, TimeUnit.MINUTES);

        return true;
    }

    private void sendEmail(String to, String subject, String content) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom("1759035967@qq.com"); // 从配置或常量中获取发件人
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true); // 开启HTML支持
        mailSender.send(message);
    }

    @Override
    public boolean verifyEmailCaptcha(String email, String userInputCaptcha) {
        String redisKey = EMAIL_CAPTCHA_PREFIX + email;
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(redisKey);

        String storedCaptcha = hashOps.get("captcha");
        if (storedCaptcha == null) {
            return false; // 验证码不存在或已过期
        }

        boolean isValid = storedCaptcha.equals(userInputCaptcha);
        if (isValid) {
            // 验证通过后删除验证码，防止重复使用
            stringRedisTemplate.delete(redisKey);
        }
        return isValid;
    }
}
